import axios from 'axios';
import type {
  AxiosInstance,
  AxiosResponse,
  InternalAxiosRequestConfig
} from 'axios';
import qs from 'qs'

// 定义响应数据类型
export interface ApiResponse<T = any> {
  code: number
  message: string
  data: T
  timestamp: number
}

// 数据格式类型
export enum ContentType {
  JSON = 'application/json',
  FORM_URLENCODED = 'application/x-www-form-urlencoded',
  FORM_DATA = 'multipart/form-data',
  TEXT = 'text/plain',
  XML = 'application/xml',
}

class HttpClient {
  private instance: AxiosInstance
  private baseURL: string

  constructor(baseURL: string = 'http://localhost:8989/api') {
    this.baseURL = baseURL
    this.instance = axios.create({
      baseURL: this.baseURL,
      timeout: 30000, // 30秒超时
      withCredentials: true, // 允许携带cookie
    })

    this.setupInterceptors()
  }

  // 设置拦截器
  private setupInterceptors(): void {
    // 请求拦截器
    this.instance.interceptors.request.use(
      (config: InternalAxiosRequestConfig) => {
        const token = this.getToken()
        if (token && config.headers) {
          config.headers.Authorization = `Bearer ${token}`
        }

        // 根据不同的ContentType处理数据
        if (config.headers?.['Content-Type'] === ContentType.FORM_URLENCODED) {
          config.data = qs.stringify(config.data)
        } else if (config.headers?.['Content-Type'] === ContentType.FORM_DATA) {
          if (
            config.data &&
            typeof config.data === 'object' &&
            !(config.data instanceof FormData)
          ) {
            const formData = new FormData()
            Object.keys(config.data).forEach((key) => {
              const value = config.data[key]
              if (Array.isArray(value)) {
                value.forEach((item) => formData.append(key, item))
              } else if (value !== undefined && value !== null) {
                formData.append(key, value)
              }
            })
            config.data = formData
          }
        }
        return config
      },
      (error: any) => {
        console.error('❌ 请求错误:', error)
        return Promise.reject(error)
      },
    )

    // 响应拦截器
    this.instance.interceptors.response.use(
      (response: AxiosResponse) => {
        const responseData = response.data
        if (responseData && typeof responseData === 'object') {
          if (responseData.code !== undefined) {
            if (responseData.code === 0) {
              return responseData
            } else {
              const error = new Error(responseData.message || '请求失败') as any
              error.code = responseData.code
              throw error
            }
          }
          return responseData
        }
        return responseData
      },
      (error: any) => {
        console.error('❌ 响应错误:', error)

        if (error.response) {
          const { status, data } = error.response

          // 处理 HTTP 错误
          switch (status) {
            case 401:
              this.handleUnauthorized()
              break
            case 403:
              this.handleForbidden()
              break
            case 404:
              this.handleNotFound()
              break
            case 500:
              this.handleServerError()
              break
            default:
              this.handleOtherError(status, data)
          }
          // 如果后端返回了错误信息，使用后端的信息
          if (data && typeof data === 'object' && data.message) {
            error.message = data.message
            error.code = data.code
          }
        } else if (error.request) {
          this.handleNetworkError()
        }

        return Promise.reject(error)
      },
    )
  }

  // 获取token（根据你的实际存储方式修改）
  private getToken(): string | null {
    return localStorage.getItem('token') || sessionStorage.getItem('token')
  }

  // 错误处理方法
  private handleUnauthorized(): void {
    console.warn('⛔ 未授权，请重新登录')
    localStorage.removeItem('token')
    sessionStorage.removeItem('token')
    window.location.href = '/login'
  }

  private handleForbidden(): void {
    console.warn('⛔ 权限不足')
  }

  private handleNotFound(): void {
    console.warn('⛔ 资源未找到')
  }

  private handleServerError(): void {
    console.error('⛔ 服务器内部错误')
  }

  private handleNetworkError(): void {
    console.error('⛔ 网络错误，请检查网络连接')
  }

  private handleUnknownError(message: string): void {
    console.error(`⛔ 未知错误: ${message}`)
  }

  private handleOtherError(status: number, data: any): void {
    console.error(`⛔ 错误 ${status}:`, data)
  }

  // 设置baseURL
  public setBaseURL(baseURL: string): void {
    this.baseURL = baseURL
    this.instance.defaults.baseURL = baseURL
  }

  // 获取axios实例（用于特殊配置）
  public getInstance(): AxiosInstance {
    return this.instance
  }
}

// 创建全局实例
const httpClient = new HttpClient()

// 直接导出配置好的 Axios 实例
export const api = httpClient.getInstance()

export default api
